package conn

import (
	"net"
	"time"
	"strconv"
	"strings"
	"github.com/sirupsen/logrus"
	"gitee.com/cooge/impush/message"
	"encoding/json"
	"errors"
	"gitee.com/cooge/impush/config"
)

type CallConnBreak func(*CHTCPconn)

type CHTCPconn struct {
	conn     *net.TCPConn
	liveTime int
	userId string
	blankNum int
	callConnBreak CallConnBreak
}

func NewCHTCPconn(conn *net.TCPConn,dealTime int,userId string)*CHTCPconn  {
	var htcp CHTCPconn
	htcp.conn = conn
	htcp.liveTime = dealTime+dealTime+20
	htcp.userId = userId
	htcp.blankNum=config.EX_C_BLANK_NUM
	return &htcp

}

func (this *CHTCPconn)Start(callConnBreak CallConnBreak){
	this.callConnBreak = callConnBreak
	go this.read()
	this.header()
}


var headerBytes = []byte("HTTP/1.1 200 OK\r\n" +
"Content-Type: text/html;charset=UTF-8\r\n" +
"Content-Language: zh\r\n" +
"Access-Control-Allow-Origin: *\r\n" +
"Transfer-Encoding: chunked\r\n")

func (this *CHTCPconn)header(){
	this.conn.Write(headerBytes)
	this.WriteBlank()
}

var endbyte = []byte("\r\n0\r\n\r\n")

var kkbytes = []byte("\r\n")


func (this *CHTCPconn) SendMessage(msg *message.Message) (int, error) {
	var msgs = []*message.Message{msg}
	return this.SendMessages(msgs)
}

func (this *CHTCPconn) SendMessages(msgs []*message.Message) (int, error) {
	data_ := make([]interface{}, 0)
	for _, v := range msgs {
		dat := make(map[string]interface{})
		dat[message.FROM] = v.Heads.Get(message.FROM)
		dat[message.BODY] = string(v.Body)
		data_ = append(data_, dat)
	}
	data, err := json.Marshal(&data_)
	if err == nil {
		return this.write(data)
	}
	return 0, errors.New(message.SEND_FAIL)
}

func(this *CHTCPconn)end(){
	this.conn.Write(endbyte)
	this.conn.Close()
}

func (this *CHTCPconn) read() {
	da := make([]byte, 1)
	_, err := this.conn.Read(da)
	if err != nil {
		logrus.Debug(this.userId,"连接断开", err)
	}
	this.conn.Close()
	this.callConnBreak(this)
}

var nlankbyte = []byte("\r\n1\r\n ")

var blankBytes=[]byte(`[]`)

func (this *CHTCPconn) WriteBlank(){
	this.blankNum--
	this.conn.Write(nlankbyte)
	this.SetReadDeadline()
	if this.blankNum==0{
		this.write(blankBytes)
	}

}

func (this *CHTCPconn) SetReadDeadline()  {
	this.conn.SetDeadline(time.Now().Add(time.Duration(this.liveTime) * time.Second))
}

func (this *CHTCPconn) write(data []byte) (int, error) {
	this.callConnBreak(this)
	da := make([]byte, 0)
	da = append(da,kkbytes...)
	ln:=len(data)
	slen:= []byte(strings.ToUpper(strconv.FormatInt((int64)(ln),16)))
	da = append(da,slen...)
	da = append(da,kkbytes...)
	da = append(da,data...)
	da = append(da,endbyte...)
	_,err:=this.conn.Write(da)
	if err!=nil{
		this.conn.Close()
		return 0,err
	}
	this.conn.Close()
	return  ln,nil
}